package com.xuecheng.common.exception;

import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.code.ErrorCode;
import com.xuecheng.common.domain.response.RestErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * <p></p>
 *
 * @Description:
 */
/**
 *     日志：
 *     	1.日志框架：{@link Slf4j}
 *     	2.Slf4j 只是一个规范的Api没有实现类：使用 log4j2
 *     	3.每一个类中如果要使用日志
 *     		private static final Logger log = xxx ：创建一个日志对象
 *     	4.Lombok使用 @Slf4j 来简化日志对象的创建
 *
 *     	全局异常处理：
 *     		1.全局异常处理的结构
 *     	    2.全局异常处理的实现技术
 *     	    3.异常处理的封装类
 *     	    4.对于异常的日志记录
 *     	    5.异常处理的过程
 *     	    	向上寻找父类型
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
	/**
	 * 处理可预知异常,业务模块中的异常信息
	 * @param e
	 * @return
	 */
	@ResponseBody
	@ExceptionHandler(BusinessException.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public RestErrorResponse customException(BusinessException e) {
		/**
		 * error方法参数:
		 * 	1 错误信息:
		 * 		在错误信息中可以使用占位符{}
		 * 	2 具体的错误内容
		 * 		e.getMessage() 会把占位符替换
		 */
		log.error("【系统异常】{}",e.getMessage(),e);
		//获得异常信息属性
		ErrorCode errorCode = e.getErrorCode();
		// 将异常信息属性的错误代码和错误信息封装到RestErrorResponse中
		return new RestErrorResponse(errorCode);

	}

	/**
	 * 处理不可预知错误（微服务框架抛出不可预知异常类型）
	 * @param e
	 * @return
	 */
	@ResponseBody
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public RestErrorResponse exception(Exception e) {
			//1.将错误信息记录到日志中
		log.error("【系统异常】{}",e.getMessage(),e);
		//2.将异常信息属性的 错误代码(code) 和 错误信息（desc）封装到 RestErrorResponse 中
		return new RestErrorResponse(String.valueOf(CommonErrorCode.UNKOWN.getCode()),
				CommonErrorCode.UNKOWN.getDesc()+":"+e.getMessage());

	}
}
